// 
// SoapTrace.Net - A soap message monitoring utility. 
// 
// Copyright (C) 2004 Matthew Ward
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// 
// Matthew Ward (mrward@users.sourceforge.net)
// 

using NUnit.Framework;
using SoapTrace.Core.Communication;
using SoapTrace.Tests.Utils;
using System;

namespace SoapTrace.Tests
{
	/// <summary>
	/// Tests the <see cref="DerivedProxyServer"/> object. 
	/// </summary>
	/// <remarks>
	/// The <see cref="DerivedProxyServer"/> object derives from the
	/// <see cref="ProxyServer"/> class and allows the testing
	/// of functionality that is available on creating a derived class.
	/// </remarks>
	[ TestFixture ]
	public class DerivedProxyServerTestFixture
	{
		/// <summary>
		/// The derived proxy server.
		/// </summary>
		private DerivedProxyServer m_DerivedProxyServer = null;

		/// <summary>
		/// Mock remote server that the proxy server will connect to and
		/// interact with.
		/// </summary>
		private MockRemoteServer m_MockRemoteServer;
		
		/// <summary>
		/// The proxy server's IP address.
		/// </summary>
		private string m_ProxyServerIPAddress = "localhost";
		
		/// <summary>
		/// The proxy server's listening port.
		/// </summary>
		private int m_ProxyServerPort = 7001;
		
		/// <summary>
		/// The remote server's IP address.
		/// </summary>
		private string m_RemoteServerIPAddress = "localhost";
		
		/// <summary>
		/// The remote server's port.
		/// </summary>
		private int m_RemoteServerPort = 8001;
		
		/// <summary>
		/// The timeout in milliseconds for proxy server actions to 
		/// complete.
		/// </summary>
		private int m_WaitTimeout = 5000;
				
		/// <summary>
		/// The client used to communicate with the remote server.
		/// </summary>
		private MockRemoteServerClient m_Client;


		/// <summary>
		/// Initialises each test by creating a 
		/// <see cref="DerivedProxyServer"/> object to test.
		/// </summary>
		[ SetUp ]
		public void Init( )
		{
			// Create a remote server client.
			m_Client = new MockRemoteServerClient( );

			// Create dummy remote server object.
			m_MockRemoteServer = new MockRemoteServer( );
			m_MockRemoteServer.Start( m_RemoteServerPort );
	
			// Start the proxy server.
			m_DerivedProxyServer = new DerivedProxyServer( );
			m_DerivedProxyServer.Start( m_ProxyServerPort,
				m_RemoteServerIPAddress,
				m_RemoteServerPort );

			// Connect the client.
			ConnectClient( );
		}

		/// <summary>
		/// Clears up after each test.
		/// </summary>
		[ TearDown ]
		public void TearDown( )
		{
			m_DerivedProxyServer.Stop( );
			m_MockRemoteServer.Stop( );
			m_Client.Close( );
		}

		/// <summary>
		/// Sends a message to the proxy server and ensures that 
		/// message is received by the derived proxy server class.
		/// </summary>
		/// <remarks>
		/// This is a test of the <see cref="TcpSocketConnection.BytesReceived"/>
		/// method.
		/// </remarks>
		[ Test ]
		public void SendClientMessage( )
		{
			string Message = "Hello";

			m_Client.Send( Message );

			string MessageReceived;

			bool Success = m_DerivedProxyServer.WaitForClientMessage( out MessageReceived, 
				m_WaitTimeout );

			Assert.IsTrue( Success, "Timed out waiting for client message." );

			Assert.AreEqual( Message,
				MessageReceived,
				"Message received by proxy server is incorrect." );
		}

		/// <summary>
		/// Sends a message to the proxy server from the server and ensures that 
		/// message is received by the derived proxy server class.
		/// </summary>
		/// <remarks>
		/// This is a test of the <see cref="TcpSocketConnection.BytesSent"/>
		/// method.
		/// </remarks>
		[ Test ]
		public void SendServerMessage( )
		{

			string Message = "Goodbye";

			m_MockRemoteServer.SendMessage( Message );

			string MessageReceived;

			bool Success = m_DerivedProxyServer.WaitForServerMessage( out MessageReceived, 
				m_WaitTimeout );

			Assert.IsTrue( Success, "Timed out waiting for server message." );

			Assert.AreEqual( Message,
				MessageReceived,
				"Message received by proxy server is incorrect." );
		}

		/// <summary>
		/// Connects the client to the proxy server and waits
		/// for the connection to be acknowledged.
		/// </summary>
		private void ConnectClient( )
		{
			// Connect a tcp client to the proxy.
			m_Client.Connect( m_ProxyServerIPAddress, m_ProxyServerPort );
			
			// Ensure the client connected to the remote server.
			bool Success = m_MockRemoteServer.WaitForConnection( m_WaitTimeout );
			
			Assert.IsTrue( Success, 
				"Proxy did not connect to remote server." );	
		}

	}
}
